using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using SkiaSharp;
using System.Security.Cryptography;
using System.Text;
using StackExchange.Redis;

namespace RabbitTraceability.API.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class CaptchaController : ControllerBase
    {
        private readonly IConnectionMultiplexer _redis;

        public CaptchaController(IConnectionMultiplexer redis)
        {
            _redis = redis;
        }

        /// <summary>
        /// 获取图片验证码（根据guid生成验证码内容，返回图片流，并将验证码存入redis）
        /// </summary>
        /// <param name="guid">前端传入的guid，若无则自动生成</param>
        /// <returns>图片验证码流，guid通过Header返回</returns>
        [HttpGet]
        public IActionResult Image([FromQuery] string? guid = null)
        {
            // 若前端未传guid则自动生成
            string realGuid;
            if (string.IsNullOrWhiteSpace(guid))
            {
                realGuid = Guid.NewGuid().ToString();
            }
            else
            {
                realGuid = guid;
            }
            // 根据guid生成验证码内容（保证同一guid生成的验证码一致）
            string captcha = GenerateCaptchaByGuid(realGuid, 4);
            // 生成图片字节流
            var imageBytes = GenerateCaptchaImage(captcha);
            // 将guid通过Header返回，便于前端获取
            // 存入redis，10分钟过期
            var db = _redis.GetDatabase();
            string redisKey = $"hekaile:{realGuid}";
            db.StringSet(redisKey, captcha, TimeSpan.FromMinutes(10));

            Response.Headers.Add("X-Captcha-Guid", realGuid);
            return File(imageBytes, "image/png");
        }

        /// <summary>
        /// 根据guid生成验证码内容（保证同一guid生成的验证码一致）
        /// </summary>
        /// <param name="guid">guid字符串</param>
        /// <param name="length">验证码长度</param>
        /// <returns>验证码字符串</returns>
        private static string GenerateCaptchaByGuid(string guid, int length)
        {
            // 对guid做MD5哈希，然后取前length位的字母数字
            using var md5 = MD5.Create();
            var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(guid));
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            var captcha = new char[length];
            for (int i = 0; i < length; i++)
            {
                captcha[i] = chars[hash[i] % chars.Length];
            }
            return new string(captcha);
        }

        /// <summary>
        /// 使用SkiaSharp生成图片验证码，内容为传入的text
        /// </summary>
        /// <param name="text">验证码内容</param>
        /// <returns>图片字节流</returns>
        private static byte[] GenerateCaptchaImage(string text)
        {
            int width = 120, height = 40;
            using var bitmap = new SKBitmap(width, height);
            using var canvas = new SKCanvas(bitmap);
            canvas.Clear(SKColors.White);

            using var paint = new SKPaint
            {
                Color = SKColors.Black,
                TextSize = 28,
                IsAntialias = true,
                Typeface = SKTypeface.Default
            };

            // 居中绘制验证码内容
            var textWidth = paint.MeasureText(text);
            var x = (width - textWidth) / 2;
            var y = (height + paint.TextSize) / 2 - 5;
            canvas.DrawText(text, x, y, paint);

            using var image = SKImage.FromBitmap(bitmap);
            using var data = image.Encode(SKEncodedImageFormat.Png, 100);
            return data.ToArray();
        }
    }
} 